﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading.Tasks;
using System.Threading;
using System.Data;

using Services.Common;
using Services.User;
using Services;

using BartonExtension;
using Model.Weixin;
using Model.App;
using Model.Images;
using Model;

using Cache.Model;
using Cache.Utils;
using Cache;

using Senparc.Weixin.MP.AdvancedAPIs.OAuth;

namespace iShangMai
{
    public static class ISMUserInfoHelper
    {
        public static Task<ISMUserinfo> GetUserInfoFromCache(string openid)
        {
            return CacheManager.instance.objectFromCacheAsync<ISMUserinfo>(openid);
        }
        public static CachingResult<ISMUserinfo> CacheUserinfo(this ISMUserinfo userinfo,string openid)
        {
            return CacheManager.instance.doCacheObject<ISMUserinfo>(userinfo, openid);
        }
        public static Task<bool> CleanUserCache(string openid)
        {
            return Task.Factory.StartNew<bool>(() =>
                {
                    return CacheManager.instance.RemoveCache(openid);
                });
        }
        public static ISMUserinfo GetUserInfoFromWeixinService(AccessToken acs_token)
        {
            OAuthUserInfo oauthinfo = OAuthApi.GetUserInfo(acs_token.access_token, acs_token.openid);
            ISMUserinfo userinfo = new ISMUserinfo()
            {
                openId = oauthinfo.openid,
                intopenid = IDGenerator.StringToInteger(oauthinfo.openid).ToString(),
                wechatName = oauthinfo.nickname,
                username = oauthinfo.nickname,
                sex = oauthinfo.sex.toEnum<Sex>(),
                headimgUrl = oauthinfo.headimgurl
            };
            return userinfo;
        }
        public static async Task<ISMServiceResult> GetUserInfoFromDB(string userIdentifier, string token)
        {
            //Get From DB
            ISMUserServiceProvider provider = (ISMUserServiceProvider)ISMServiceStack.sharedInstance[ISMServiceStackKeys.USER];

            ISMServiceModel model = new ISMServiceModel();
            model.operationIdentifier = ISMUserServiceProvider.USER_GET_INFO;

            Dictionary<string, object> param = new Dictionary<string, object>();
            param.Add("userIdentifier", userIdentifier);
            param.Add("token", token);

            model.userinfo = param;
            ISMServiceResult dbResult = await provider.doProcess(model);
            return dbResult;
        }
        public static async Task<ISMUserinfo> GetUserInfo(AccessToken acs_token,string token)
        {
            try
            {
                string userIdentifier = IDGenerator.StringToInteger(acs_token.openid).ToString();
                ISMUserinfo userinfo = null;
                ISMServiceResult DBGetterResult = await GetUserInfoFromDB(userIdentifier, token);
                if (DBGetterResult.isOperationSuccess)
                {
                    userinfo = (ISMUserinfo)DBGetterResult.dbReturningState;
                }
                else
                {
                    if (DBGetterResult.errorCode == ISMServiceResultErrorCodes.ERR_CODE_USER_OPENID_NOT_EXISTS)
                    {
                        //Get Userinfo from weixin
                        userinfo = GetUserInfoFromWeixinService(acs_token);

                        ISMUpdateUserInfoRequest request = new ISMUpdateUserInfoRequest();
                        request.userinfo = userinfo;
                        request.token = token;

                        //Regsiter User
                        ISMUserServiceProvider provider = (ISMUserServiceProvider)ISMServiceStack.sharedInstance[ISMServiceStackKeys.USER];

                        ISMServiceModel reg_model = new ISMServiceModel();
                        reg_model.operationIdentifier = ISMUserServiceProvider.USER_UPDATE_INFO;
                        reg_model.userinfo = request;
                        var update_result = await provider.doProcess(reg_model);
                        if (update_result.isOperationSuccess)
                        {
                            userinfo = (ISMUserinfo)update_result.dbReturningState;
                        }
                        else
                        {
                            return null;
                        }
                    }
                }

                if (!JSSDKAccess.loaded)
                {
                    JSSDKAccess.Init();
                }
                string ticket_ = JSSDKAccess.js_ticket;

                userinfo.ticket = ticket_;

                return userinfo;
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
}